﻿using System;
using System.Configuration;
using SimpleServiceBus.Configuration;
using SimpleServiceBus.EndpointManagement.Server.MessageHandlers;
using SimpleServiceBus.Utilities.Email;

namespace SimpleServiceBus.EndpointManagement.Server.Configuration
{
    public class EndpointMonitorConfiguration : ConfigurationSection
    {
        [ConfigurationProperty("endpointMonitorInterval", IsRequired = false)]
        public TimeSpan EndpointMonitorInterval
        {
            get { return (TimeSpan) base["endpointMonitorInterval"]; }
            set { base["endpointMonitorInterval"] = value; }
        }

        [ConfigurationProperty("statusSummaryBroadcastInterval", IsRequired = false)]
        public TimeSpan StatusBroadcastInterval
        {
            get { return (TimeSpan) base["statusSummaryBroadcastInterval"]; }
            set { base["statusSummaryBroadcastInterval"] = value; }
        }

        [ConfigurationProperty("smtpHostName")]
        public string SmtpHostName
        {
            get { return (string) base["smtpHostName"]; }
            set { base["smtpHostName"] = value;}
        }

        [ConfigurationProperty("smtpPort",DefaultValue=25)]
        public int SmtpPort
        {
            get { return (int)base["smtpPort"]; }
            set { base["smtpPort"] = value; }
        }

        [ConfigurationProperty("emailFromAddress",DefaultValue="ssb_notification@noreply.com")]
        public string EmailFromAddress
        {
            get { return (string)base["emailFromAddress"]; }
            set { base["emailFromAddress"] = value; }
        }

        [ConfigurationProperty("webServiceUri",DefaultValue="http://localhost:8888")]
        public string WebServiceUri
        {
            get { return (string) base["webServiceUri"]; }
            set { base["webServiceUri"] = value;}
        }

        public void Configure(IEndpointBuilder endpoint)
        {
            var monitor = endpoint.GetService<IEndpointMonitorServerService>();
            if (EndpointMonitorInterval > TimeSpan.MinValue)
                monitor.EndpointMonitorInterval = EndpointMonitorInterval;

            var aggregator = endpoint.GetService<IEndpointStatusAggregationService>();
            if (StatusBroadcastInterval > TimeSpan.MinValue)
                aggregator.StatusBroadcastInterval = StatusBroadcastInterval;
        }

        public static void ConfigureEndpointAsEndpointMonitor(IEndpointBuilder endpoint)
        {
            endpoint.RegisterService<IEndpointMonitorServerService, EndpointMonitorServer>();
            endpoint.RegisterService<IEndpointStatusAggregationService, EndpointStatusAggregationService>();
            endpoint.RegisterService<IEndpointStatusPersistenceService, EndpointStatusPersistenceService>();
            endpoint.RegisterService<IEmailService, SmtpEmailService>();
            
            endpoint.MessageHandlers.RegisterMessageHandlerAssembly(typeof(EndpointStatusMessageHandler).Assembly);


            EndpointMonitorConfiguration config = GetConfiguration();
            if (config != null)
            {
                config.Configure(endpoint);

                var emailService = endpoint.GetService<IEmailService>();
                if (emailService != null && !String.IsNullOrEmpty(config.SmtpHostName))
                {
                    emailService.ServerName = config.SmtpHostName;
                    emailService.PortNumber = config.SmtpPort;
                    emailService.FromAddress = config.EmailFromAddress;
                }
            }
        }

        public static void ConfigureEndpointAsEndpointMonitor(IEndpointBuilder endpoint, TimeSpan monitorInterval, TimeSpan broadcastInterval)
        {
            ConfigureEndpointAsEndpointMonitor(endpoint);
            
            endpoint.GetService<IEndpointMonitorServerService>().EndpointMonitorInterval = monitorInterval;
            endpoint.GetService<IEndpointStatusAggregationService>().StatusBroadcastInterval = broadcastInterval;
        }

        public static EndpointMonitorConfiguration GetConfiguration()
        {
            return GetConfiguration("endpointMonitorServer");
        }

        public static EndpointMonitorConfiguration GetConfiguration(string sectionName)
        {
            return ConfigurationManager.GetSection(sectionName) as EndpointMonitorConfiguration;
        }
    }
}